﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Windows;
using System.Windows.Threading;
using System.Threading;
using System.Diagnostics;
using FinPlusAssembler;
using FinPlusInterfaces;

namespace FinPlusCompView
{
    public class FinPlusWindowHelper : FinPlusControl, IWindowHelper
    {
        private static int _angle, _angleChange = 30, _radius = 100;

        //public
        public void OpenSync(string templatePath, string name, object[,] inject, Env env, ShowType showType = ShowType.Show, string callerId = "", string query = "", bool hasState = false, bool hasHeader = true, bool topmost = false)
        {
            var window = new FinPlusWindow(templatePath, callerId, hasHeader);
            window.SetTitle(name);
            var view = IOC.New<IPods>(templatePath + ".view", "root/current", query).Construct(name, env, inject.Append(new object[,] { { "Window", window } }));
            window.Dock(view.Object, "");
            Show(window, name, showType, hasState, topmost);
        }

        public void OpenAsync(string templatePath, string name, object[,] inject, Env env, ShowType showType = ShowType.Show, string callerId = "", string query = "", bool hasState = false, bool hasHeader = true, bool topmost = false)
        {
            try
            {
                var thread = new Thread(new ThreadStart(() =>
                {
                    var window = new FinPlusWindow(templatePath, callerId, hasHeader);
                    if (showType.Equals(ShowType.Dispatch))
                    {
                        SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));
                        window.Closed += (s, a) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);
                    }

                    var view = IOC.New<IPods>(templatePath + ".view", "root/current", query).Construct(name, env, inject.Append(new object[,] { { "Window", window } }));
                    window.Dock(view.Object, "");
                    Show(window, name, showType, hasState, topmost);
                    Dispatcher.Run();
                }));

                thread.SetApartmentState(ApartmentState.STA);
                thread.IsBackground = showType.Equals(ShowType.BackGround);
                thread.Start();
            }
            catch (Exception e)
            {
                Level.Error.Log(e.Message, e);
            }
        }

        public void OpenProcess(string templatePath, string name, Env env, ShowType showType = ShowType.Show, string callerId = "", string query = "", bool hasState = false, bool hasHeader = true, bool topmost = false)
        {
            try
            {
                if(Debugger.IsAttached)
                    OpenSync(templatePath, name, null, env, showType, callerId, query, hasState, hasHeader, topmost);
                else
                    Process.Start(new ProcessStartInfo() { FileName = "FinPlusClientShell.exe", Arguments = string.Format("{0} {1} {2} {3} '{4}' '{5}' {6} {7} {8}", templatePath, name, env.ToString(), showType.ToString(), callerId, query.Replace(' ','¬'), hasState, hasHeader, topmost) });
            }
            catch (Exception e)
            {
                Level.Warning.Log(e.Message, e);
            }
        }

        //private
        private void Show(FinPlusWindow window, string name, ShowType showType, bool hasState, bool topmost)
        {
            window.SetTitle(name);
            window.Topmost = topmost;
            if (hasState)
                window.LoadState();

            if(showType.Equals(ShowType.Central))
                SetCentral(window);
            else if(showType.Equals(ShowType.Mouse))
                SetMouse(window);

            if (showType.Equals(ShowType.Dialog))
                window.ShowDialog();
            else
                window.Show();
        }

        private void SetCentral(FinPlusWindow window)
        {
            System.Media.SystemSounds.Beep.Play();
            var p = new Point(System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width / 2, System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height / 2);
            _angle = (_angle + _angleChange) % 360;
            window.SizeToContent = SizeToContent.WidthAndHeight;
            window.WindowStyle = WindowStyle.None;
            window.ResizeMode = ResizeMode.NoResize;
            window.Left = _radius * Math.Cos(Math.PI * _angle / 180.0) + p.X;
            window.Top = _radius * Math.Sin(Math.PI * _angle / 180.0) + p.Y;
        }

        private void SetMouse(FinPlusWindow window)
        {
            System.Media.SystemSounds.Beep.Play();
            var p = System.Windows.Forms.Control.MousePosition;
            window.SizeToContent = SizeToContent.WidthAndHeight;
            window.WindowStyle = WindowStyle.None;
            window.ResizeMode = ResizeMode.NoResize;
            window.Left = p.X - 300;
            window.Top = p.Y - 150;
        }
    }
}
